package com.component.encrypt;

import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;

public class AES {
	/**
	 * ECB加密模式
	 * 
	 * @param data
	 * @param key
	 * @return
	 */
	public static byte[] encrypt(byte[] data, byte[] key) {
		CheckUtils.notEmpty(data, "data");
		CheckUtils.notEmpty(key, "key");
		if (key.length != 16) {
			throw new RuntimeException("Invalid AES key length (must be 16 bytes)");
		}
		try {
			SecretKeySpec secretKey = new SecretKeySpec(key, "AES");
			/*
			 * byte[] enCodeFormat = secretKey.getEncoded(); SecretKeySpec
			 * seckey = new SecretKeySpec(enCodeFormat, "AES");
			 */
			Cipher cipher = Cipher.getInstance(Config.TRANSFORMATION_AES_ECB);// 创建密码器
			cipher.init(Cipher.ENCRYPT_MODE, secretKey);// 初始化
			byte[] result = cipher.doFinal(data);
			return result; // 加密
		} catch (Exception e) {
			throw new RuntimeException("encrypt fail!", e);
		}
	}

	/**
	 * CBC加密模式
	 * 
	 * @param data
	 * @param key
	 * @param iv
	 * @return
	 */
	public static byte[] encrypt(byte[] data, byte[] key, byte[] iv) {
		CheckUtils.notEmpty(data, "data");
		CheckUtils.notEmpty(key, "key");
		CheckUtils.notEmpty(iv, "iv");
		if (key.length != 16) {
			throw new RuntimeException("Invalid AES key length (must be 16 bytes)");
		}
		try {
			SecretKeySpec secretKey = new SecretKeySpec(key, "AES");
			IvParameterSpec ivspec = new IvParameterSpec(iv);
			Cipher cipher = Cipher.getInstance(Config.TRANSFORMATION_AES_CBC);// 创建密码器
			cipher.init(Cipher.ENCRYPT_MODE, secretKey, ivspec);
			byte[] result = cipher.doFinal(data);
			return result; // 加密
		} catch (Exception e) {
			throw new RuntimeException("encrypt fail!", e);
		}
	}

	/**
	 * ECB解密模式
	 * 
	 * @param data
	 * @param key
	 * @return
	 */
	public static byte[] decrypt(byte[] data, byte[] key) {
		CheckUtils.notEmpty(data, "data");
		CheckUtils.notEmpty(key, "key");
		if (key.length != 16) {
			throw new RuntimeException("Invalid AES key length (must be 16 bytes)");
		}
		try {
			SecretKeySpec secretKey = new SecretKeySpec(key, "AES");
			/*
			 * byte[] enCodeFormat = secretKey.getEncoded(); SecretKeySpec
			 * seckey = new SecretKeySpec(enCodeFormat, "AES");
			 */
			Cipher cipher = Cipher.getInstance(Config.TRANSFORMATION_AES_ECB);// 创建密码器
			cipher.init(Cipher.DECRYPT_MODE, secretKey);// 初始化
			byte[] result = cipher.doFinal(data);
			return result; // 加密
		} catch (Exception e) {
			throw new RuntimeException("decrypt fail!", e);
		}
	}

	/**
	 * CBC解密模式
	 * 
	 * @param data
	 * @param key
	 * @param iv
	 * @return
	 */
	public static byte[] decrypt(byte[] data, byte[] key, byte[] iv) {
		CheckUtils.notEmpty(data, "data");
		CheckUtils.notEmpty(key, "key");
		CheckUtils.notEmpty(iv, "iv");
		if (key.length != 16) {
			throw new RuntimeException("Invalid AES key length (must be 16 bytes)");
		}
		try {
			SecretKeySpec keyspec = new SecretKeySpec(key, "AES");
			IvParameterSpec ivspec = new IvParameterSpec(iv);
			Cipher cipher = Cipher.getInstance(Config.TRANSFORMATION_AES_CBC);// 创建密码器
			cipher.init(Cipher.DECRYPT_MODE, keyspec, ivspec);
			byte[] original = cipher.doFinal(data);
			return original;
		} catch (Exception e) {
			e.printStackTrace();
			return null;
		}
	}
}
